home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / flying-6.11 / sccs / s.xgraph.C < prev    next >
Encoding:
Text File  |  1995-06-30  |  19.5 KB  |  843 lines

  1. h25756
  2. s 00001/00001/00810
  3. d D 1.3 95/06/29 13:36:06 tom 3 2
  4. c Port to SCO
  5. e
  6. s 00005/00001/00806
  7. d D 1.2 95/05/05 08:02:49 tom 2 1
  8. c Port to ODT 3.0
  9. e
  10. s 00807/00000/00000
  11. d D 1.1 95/05/04 23:26:28 tom 1 0
  12. c date and time created 95/05/04 23:26:28 by tom
  13. e
  14. u
  15. U
  16. t
  17. T
  18. I 1
  19.  
  20. D 2
  21. #ifdef SOLARIS
  22. E 2
  23. I 2
  24. #if defined(SOLARIS)
  25. E 2
  26. extern "C" int gettimeofday(struct timeval *tp);
  27. I 2
  28. #endif
  29.  
  30. D 3
  31. #if defined(SCO)
  32. E 3
  33. I 3
  34. #if defined(SCO_ODT3)
  35. E 3
  36. extern "C" int gettimeofday(struct timeval *tp, struct timezone *tzp);
  37. E 2
  38. #endif
  39.  
  40. #include "pointer.h"
  41. #include "stipple.h"
  42. #ifndef _xsound_h
  43. #    include "xsound.h"
  44. #endif
  45.  
  46. #ifndef _game_h
  47. #    include "game.h"
  48. #endif
  49.  
  50. #include <stdarg.h>
  51.  
  52. Display    *dpy;
  53. Window    win, new_root;
  54. Colormap    cmap;
  55. int        scr;
  56.  
  57. static int        nbg_cols_all;
  58. static int        bg_unused;
  59. static int        nball_cols_to_alloc;
  60.  
  61. Pixmap    pointer_pmap;        // Pixmap (wird vom PBall benutzt)
  62. int        pointer_off_x, pointer_off_y;
  63.  
  64. static Pixmap        stipple_pmap=0;
  65. static const int    stipple_sz=128;
  66.  
  67. static unsigned long    start_seconds;
  68.  
  69. static int    info_ch = 0;
  70.  
  71. #ifdef STATISTICS
  72. static    GC    gc_text;
  73. static int    info_cw = 0;
  74.  
  75. static XFontStruct *fs = 0;
  76. static Font    info_font;
  77. static unsigned long info_fg, info_bg;
  78. static const int info_width = 16;
  79. static int info_offset = 0;
  80.  
  81. void showinfo( StatType stat, const char *info ) {
  82. static info_toggle=0;
  83.  
  84.     if (new_root) {
  85.         int len = strlen(info);
  86.         if (stat==OffsetInfo) {
  87.             if (len) {
  88.                 info_toggle^=1;
  89.                 if (info_toggle) {
  90.                     XSetForeground( dpy, gc_text, info_bg );
  91.                     XSetBackground( dpy, gc_text, info_fg );
  92.                 }
  93.             }
  94.             else {
  95.                 info = "                  ";
  96.                 len = 20;
  97.             }
  98.         }
  99.         XDrawImageString( dpy, new_root,
  100.             gc_text,
  101.             info_offset - (stat+1)*info_width*info_cw,
  102.             DisplayHeight(dpy,scr)- 1,
  103.             info, len);
  104.  
  105.         if ((stat==OffsetInfo) && (info_toggle)) {
  106.             XSetForeground( dpy, gc_text, info_fg );
  107.             XSetBackground( dpy, gc_text, info_bg );
  108.         }
  109.     }
  110. }
  111. #endif
  112.  
  113. static void InitTime() {
  114. struct timeval start;
  115.  
  116. #ifdef SOLARIS
  117.     gettimeofday( &start );
  118. #else
  119.     gettimeofday( &start, NULL );
  120. #endif
  121.     start_seconds = start.tv_sec;
  122. }
  123.  
  124. double GetCurrentTime() {
  125. struct timeval    current;
  126.  
  127. #ifdef SOLARIS
  128.     gettimeofday( ¤t );
  129. #else
  130.     gettimeofday( ¤t, NULL );
  131. #endif
  132.     return( ((double)(current.tv_sec-start_seconds))+(current.tv_usec/1000000.0) );
  133. }
  134.  
  135.  
  136. GC        gc_default;
  137.  
  138. GC        gc_lay1;
  139. GC        gc_lay2;
  140. GC        gc_cursor;
  141.  
  142. GC        gc_current;
  143.  
  144. GC        gc_bxor;
  145. GC        gc_bclear;
  146.  
  147. GC        gc_ballwhite;
  148. GC        gc_ball[MAX_BALL];
  149.  
  150.  
  151. void SetBgColor( ColorId col ) {
  152.     gc_current = gc_default;
  153.  
  154. //
  155. // set the foreground pixel
  156. //
  157.     if (col&BG_MASK) {
  158.         XSetForeground( dpy, gc_current, ball_pix[0]|bg_pix[col&COLOR_MASK] );
  159.     }
  160.     else if (col&STAT_MASK) {
  161.         XSetForeground( dpy, gc_current, stat_pix[col&COLOR_MASK] );
  162.     }
  163.     else {
  164.         XSetForeground( dpy, gc_current, ball_pix[col&COLOR_MASK] );
  165.     }
  166.  
  167. //
  168. // set background (when in mixed mode)
  169. //
  170.     if (col&MIX_MASK) {
  171.     //
  172.     // set background color
  173.     //
  174.         if ((col>>COLOR_BITS)&BG_MASK) {
  175.             XSetBackground( dpy, gc_current,
  176.                                 ball_pix[0]|bg_pix[(col>>COLOR_BITS)&COLOR_MASK] );
  177.         }
  178.         else if ((col>>COLOR_BITS)&STAT_MASK) {
  179.             XSetBackground(dpy,gc_current,stat_pix[(col>>COLOR_BITS)&COLOR_MASK]);
  180.         }
  181.         else {
  182.             XSetBackground(dpy,gc_current,ball_pix[(col>>COLOR_BITS)&COLOR_MASK]);
  183.         }
  184.  
  185.     //
  186.     // set (or create) background stipple
  187.     //
  188.         if (col&RAND_MASK) {
  189.         Pixmap rand_stipple_pmap=XCreatePixmap(dpy,win,stipple_sz,stipple_sz,1);
  190.             GC    gc = XCreateGC( dpy, rand_stipple_pmap, 0, 0l );
  191.             XSetFunction(dpy,gc,GXset);
  192.             XFillRectangle(dpy,rand_stipple_pmap,gc,0,0,stipple_sz,stipple_sz);
  193.             XSetFunction(dpy,gc,GXclear);
  194.             for (int i=stipple_sz*stipple_sz/
  195.                             ((int)((col&RAND_MASK)>>RAND_SHIFT)+1); i>0;i--) {
  196.                 XDrawPoint(dpy,rand_stipple_pmap,gc,rand()%stipple_sz,rand()%stipple_sz);
  197.             }
  198.             XFreeGC(dpy,gc);
  199.             XSetStipple( dpy, gc_current, rand_stipple_pmap );
  200.         }
  201.         else {
  202.             XSetStipple( dpy, gc_current, stipple_pmap );
  203.         }
  204.         XSetFillStyle( dpy, gc_current, FillOpaqueStippled );
  205.     }
  206.     else {
  207.         XSetFillStyle( dpy, gc_current, FillSolid );
  208.     }
  209. }
  210.  
  211. int StoreColor( unsigned pixel ) {
  212.             long    stat=-1;
  213. unsigned long    bgc;
  214.             int    nbgc;
  215. unsigned long    shc;
  216.             int    nshc;
  217. unsigned long    cuc;
  218. unsigned long    bc;
  219.             int    nbc;
  220.  
  221.         bgc = pixel&bg_mask;            // Hintergrund
  222.         for (nbgc=(nbg_cols_all-1)-1;nbgc>=0;nbgc--) {// passenden Index suchen
  223.             if (bg_pix[nbgc]==bgc)        break;
  224.         }
  225.         if ((bgc)&&nbgc>=nbg_cols) {
  226.                 stat = nbgc-nbg_cols;                // unbenutztes Pixel -> static
  227.         }
  228.  
  229.         shc = pixel&shade_mask;        // Schattierung
  230.         for (nshc=0;nshc<nshade_cols;nshc++) {            // passenden Index suchen
  231.             if (shade_pix[nshc]==shc)        break;
  232.         }
  233.         if ((shc)&&nshc>=nshade_cols) {
  234.                 printf( "not implemented: shaded %d free for static\n", pixel );
  235.                 return -1;        // unbenutztes Pixel
  236.         }
  237.  
  238.         cuc = pixel&cursor_mask;   // Cursor
  239.  
  240.         bc  = pixel-bgc-shc-cuc;    // Ballfarbe
  241.         for (nbc=0;nbc<nball_cols_to_alloc;nbc++) {        // passenden Index suchen
  242.             if (ball_pix[nbc]==bc)        break;
  243.         }
  244.         if (nbc>=nball_cols_to_alloc)        return -1;
  245.  
  246.         if (nbc>=nball_cols) {
  247.             stat = nball_cols*bg_unused + (nbc-nball_cols)*(nbg_cols_all)
  248.                     + ((nbgc>=0)?nbgc+1:0);
  249.         }
  250.         else {
  251.             if (stat>=0)    stat+=(nbc*bg_unused);
  252.         }
  253.  
  254. XColor     col;
  255.  
  256.     if (cuc&&(stat<nstat_cols)) {
  257.         XParseColor(dpy,cmap,cursor_col, &col );
  258.     }
  259.     else {
  260.         if (stat>=0) {
  261.             if (stat<nstat_cols) {
  262.                 XParseColor(dpy,cmap,stat_col[stat], &col );
  263.                 if (!shc) {
  264.                     DBG2( ShowColors, "Static %2ld at pixel %3d\n", stat, pixel );
  265.                     stat_pix[stat] = pixel;
  266.                 }
  267.             }
  268.             else return -1;
  269.         }
  270.         else if (nbc) {
  271.                 XParseColor(dpy,cmap,ball_col[nbc], &col );        // RGB-Werte lesen
  272.         }
  273.         else if (bgc) {
  274.                 XParseColor(dpy,cmap,bg_col[nbgc], &col );        // RGB-Werte lesen
  275.         }
  276.         else    XParseColor(dpy,cmap,ball_col[0], &col );
  277.  
  278.         if (shc) {
  279.             XColor    scol;
  280.             XParseColor(dpy,cmap,shade_col[nshc], &scol );    // RGB-Werte lesen
  281.  
  282.             col.red   = (col.red  *m[nshc] + scol.red  *d[nshc])/(m[nshc]+d[nshc]);
  283.             col.green = (col.green*m[nshc] + scol.green*d[nshc])/(m[nshc]+d[nshc]);
  284.             col.blue  = (col.blue *m[nshc] + scol.blue *d[nshc])/(m[nshc]+d[nshc]);
  285.         }
  286.     }
  287.  
  288.     col.pixel = pixel;
  289.     col.flags = DoRed|DoGreen|DoBlue;
  290.     XStoreColor( dpy,cmap,&col);
  291.     return 0;
  292. }
  293.  
  294. void StoreColors() {
  295.     for (int i=0;i<256;i++)    StoreColor(i);
  296. }
  297.  
  298.  
  299. void AllocColors() {
  300. unsigned long plane_mask[8];
  301. int    nplanes = 0;
  302. int    n;
  303.  
  304.     nball_cols_to_alloc = nball_cols;
  305. //
  306. // Ausrechnen, wieviele Planes ben÷tigt werden
  307. //
  308.     n = nbg_cols;        // Planes fⁿr Hintergrund sammeln
  309.     while( n )    { nplanes++;    n>>=1; }
  310.     nbg_cols_all = (1<<nplanes);
  311.     bg_unused    = nbg_cols_all-1-nbg_cols;
  312.     n = nshade_cols;
  313.     while( n )    { nplanes++;    n>>=1; }
  314.     if (cursor_col)    nplanes++;
  315.  
  316. //
  317. // Anfordern der Farben
  318. //
  319.     DBG1( ShowColors, "Graphic: %d planes\n", nplanes );
  320.     DBG1( ShowColors, "Graphic: %d ball colors\n", nball_cols );
  321.     DBG1( ShowColors, "Graphic: %d static colors\n", nstat_cols );
  322.     while (nstat_cols>nball_cols*bg_unused
  323.                             +(nball_cols_to_alloc-nball_cols)*(nbg_cols_all)) {
  324.         nball_cols_to_alloc++;
  325.     }
  326.     DBG1( ShowColors, "Graphic: %d statics 'between planes'\n", nball_cols*bg_unused );
  327.     DBG1( ShowColors, "Graphic: allocating %d ball colors\n", nball_cols_to_alloc );
  328.  
  329.     cmap = DefaultColormap( dpy, scr );
  330.     if (XAllocColorCells( dpy, cmap, False,
  331.                     plane_mask, nplanes, ball_pix, nball_cols_to_alloc )==0) {
  332.         DBG0( UnixTrace,
  333.                         "Allocation of colors failed - creating local colormap.\n" );
  334.         cmap= XCreateColormap(dpy,win,DefaultVisual(dpy,scr),AllocNone);
  335.         if (XAllocColorCells( dpy, cmap, False,
  336.                     plane_mask, nplanes, ball_pix, nball_cols_to_alloc )==0) {
  337.                 fprintf(stderr, "not enough colors: " );
  338.                 fprintf(stderr, "I need %d colors + %d planes.\n",
  339.                             nball_cols_to_alloc, nplanes );
  340.                 exit(0);
  341.         }
  342.         if (new_root) {
  343.                 XSetWindowAttributes    attrib;
  344.                 attrib.colormap = cmap;
  345.                 XChangeWindowAttributes( dpy, new_root, CWColormap, &attrib );
  346.         }
  347.         else    XSetWindowColormap( dpy, win, cmap );
  348.         XSync(dpy,0);
  349.     }
  350.  
  351. //
  352. // Verteilen der Planes auf die Farben
  353. //
  354. int c=0;
  355.     for (n=0;n<nbg_cols+bg_unused;n++) {
  356.         bg_pix[n] = 0;
  357.         if ((n+1)&1)        bg_pix[n]+=plane_mask[c+0];
  358.         if ((n+1)&2)        bg_pix[n]+=plane_mask[c+1];
  359.         if ((n+1)&4)        bg_pix[n]+=plane_mask[c+2];
  360.     }
  361.     n=nbg_cols;
  362.     bg_mask=0;
  363.     while(n)        { bg_mask+=plane_mask[c++];        n>>=1; }
  364.  
  365.     for (n=0;n<nshade_cols;n++) {
  366.         shade_pix[n] = 0;
  367.         if ((n+1)&1)        shade_pix[n]+=plane_mask[c+0];
  368.         if ((n+1)&2)        shade_pix[n]+=plane_mask[c+1];
  369.         if ((n+1)&4)        shade_pix[n]+=plane_mask[c+2];
  370.     }
  371.     n=nshade_cols;
  372.     shade_mask=0;
  373.     while(n)        { shade_mask+=plane_mask[c++];    n>>=1; }
  374.  
  375.     if (cursor_col) {
  376.         cursor_mask = plane_mask[c];
  377.     }
  378.  
  379.     ball_mask=0;
  380.     for (n=0;n<nball_cols_to_alloc;n++) {
  381.         ball_mask|=ball_pix[n];
  382.     }
  383. //
  384. // Farben eintragen
  385. //
  386.     StoreColors();                            // Farben in Tabelle eintragen
  387. //
  388. // GC's besetzen
  389. //
  390. unsigned long    value_mask;
  391. XGCValues        values;
  392.  
  393.     value_mask =    GCPlaneMask | GCForeground | GCBackground | GCFunction
  394.                     |    GCArcMode | GCStipple | GCFillStyle | GCGraphicsExposures;
  395.     values.graphics_exposures = False;
  396.     values.foreground = 0xffff;
  397.     values.background = 0;
  398.     values.function    = GXxor;
  399.     values.arc_mode    = ArcChord;        // statt ArcPieSlice
  400.     stipple_pmap      =
  401.     values.stipple        = XCreateBitmapFromData( dpy, RootWindow( dpy, scr ),
  402.                                     stipple_bits, stipple_width, stipple_height );
  403.     values.fill_style    = FillSolid;
  404. #ifdef STATISTICS
  405.     values.font= info_font;
  406.     if (values.font)    value_mask|=GCFont;
  407. #endif
  408.  
  409.     values.plane_mask  = bg_pix[0];
  410.     gc_lay1 = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  411.     values.plane_mask  = shade_pix[0];
  412.     gc_lay2 = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  413.  
  414.     values.plane_mask  = cursor_mask;
  415.     gc_cursor = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  416.  
  417. //
  418. // Default Graphic-Context erzeugen
  419. //
  420.     values.foreground = ball_pix[0];
  421.     values.plane_mask = ball_mask | shade_pix[0];        // Arbeiten in lay2
  422.     values.function   = GXxor;
  423.     gc_bxor = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  424.     values.function   = GXclear;
  425.     gc_bclear = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  426.  
  427.     values.plane_mask    = ball_mask|shade_mask|bg_mask|cursor_mask;
  428.     values.function    = GXcopy;
  429.     gc_default = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  430.  
  431.     values.plane_mask    = ball_mask;
  432.     gc_ball[0] = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  433. //
  434. // Kontext fⁿr den Text
  435. //
  436. #ifdef STATISTICS
  437.     values.foreground = info_fg = ball_pix[0];
  438.     values.background = info_bg = GetAllocatedPixel( "black" );
  439.     values.plane_mask  = AllPlanes;
  440.     gc_text    = XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  441.  
  442.     info_offset = (DisplayWidth(dpy,scr)+max_x)/2;
  443. #endif
  444. //
  445. // GC's fⁿr die Ballfarben
  446. //
  447. unsigned long white_pix=0;
  448.  
  449.     values.fill_style = FillSolid;
  450.     values.plane_mask = ball_mask;
  451.     values.function    = GXxor;
  452.     values.background = 0;
  453.     if (deluxe) {
  454.         white_pix = GetAllocatedPixel( "ivory" );
  455.         if (!white_pix) {
  456.             fprintf( stderr, "white color 'ivory' missing for ball-underground\n");
  457.             exit(-1);
  458.         }
  459.         values.foreground = (white_pix^ball_pix[0]);
  460.         gc_ballwhite=XCreateGC(dpy,RootWindow(dpy,scr),value_mask,&values);
  461.     }
  462.  
  463.  
  464.     for (int i=0;i<nball_ids;i++) {
  465.         ColorId    col = ball_ids[i];
  466.  
  467.         if (deluxe) values.foreground = white_pix^ball_pix[col&COLOR_MASK];
  468.         else            values.foreground = ball_pix[0]^ball_pix[col&COLOR_MASK];
  469.         if (col&MIX_MASK) {
  470.             values.foreground = ball_pix[0]^ball_pix[(col>>COLOR_BITS)&COLOR_MASK];
  471.             values.fill_style = FillOpaqueStippled;
  472.         }
  473.         else {
  474.             values.fill_style = FillSolid;
  475.         }
  476.  
  477.         gc_ball[i]=XCreateGC( dpy, RootWindow( dpy, scr ), value_mask, &values );
  478.     }
  479. //
  480. // Pixmaps erzeugen
  481. //
  482.     pointer_pmap = XCreatePixmapFromBitmapData(dpy,win,
  483.             pointer_bits, pointer_width, pointer_height, cursor_mask, 0,
  484.             DefaultDepth(dpy,scr) );
  485.     pointer_off_x = pointer_x_hot;
  486.     pointer_off_y = pointer_y_hot;
  487.  
  488. #ifdef DEBUG
  489.     if (debug&Sync) {
  490.         XSynchronize(dpy,1);
  491.     }
  492.     if ((debug&ShowSubWindow)&&(!new_root)) { 
  493.         XSizeHints                hints;
  494.  
  495.         hints.flags = USPosition | USSize | PAspect | PMinSize | PMaxSize;
  496.         hints.x = (DisplayWidth(dpy,scr) -max_x)/2;
  497.         hints.y = 0;
  498.         hints.width  = hints.min_width  = hints.max_width  = max_x;
  499.         hints.height = hints.min_height = hints.max_height = max_y;
  500.         XSetNormalHints( dpy,win,&hints );
  501.     }
  502. #endif
  503.  
  504.  
  505. #ifdef DEBUG
  506.     if (debug&ShowColors) {
  507. Window    help;
  508. const int lpixs_x = 16;
  509. const int lpixs_y = 16;
  510. const int d=16;
  511. const int o=2;
  512.  
  513.         help = CreateWindow("Farbtabelle",lpixs_x*(d+o)+1 ,lpixs_y*(d+o)+1);
  514.         for (int px=0;px<lpixs_x;px++) {
  515.             for (int py=0;py<lpixs_y;py++) {
  516.                 if (!StoreColor(px+py*lpixs_x)) {
  517.                     XSetForeground(dpy,gc_default,px+py*lpixs_x);
  518.                     XFillRectangle(dpy,help,gc_default,1+px*(d+o),1+py*(d+o),d,d );
  519.                 }
  520.             }
  521.         }
  522.     }
  523. #endif
  524. }
  525.  
  526.  
  527. void MapMainWindow() {
  528. XEvent    event;
  529.  
  530.     XSetWindowBackground( dpy, win, ball_pix[0] );
  531.     XMapRaised( dpy, win );
  532.     if (new_root) {
  533.         XSetWindowBackground( dpy, new_root, GetAllocatedPixel("black") );
  534.         XMapRaised( dpy, new_root );
  535.         XInstallColormap( dpy, cmap );
  536.     }
  537.     XWindowEvent( dpy, win, ExposureMask, &event );
  538.     XSetInputFocus( dpy, win, RevertToNone, CurrentTime );
  539. }
  540.  
  541.  
  542. Window CreateWindow( const char *name, int width, int height )
  543. {
  544. Window    win;
  545. XSetWindowAttributes    attrib;
  546. XSizeHints                hints;
  547. XEvent    event;
  548. static    int    offx=0;
  549. const    frame = 11;
  550.  
  551.     win = XCreateSimpleWindow( dpy, RootWindow(dpy,scr),
  552.                     0, 0, width, height,
  553.                     0, ball_pix[0], ball_pix[0] );
  554.     attrib.colormap = cmap;
  555.     XChangeWindowAttributes( dpy, win, CWColormap, &attrib );
  556.  
  557.     hints.flags = USPosition | USSize | PAspect | PMinSize | PMaxSize;
  558.     hints.x = DisplayWidth(dpy,scr) -offx-width-frame;
  559.     hints.y = DisplayHeight(dpy,scr)-height,
  560.     hints.width  = hints.min_width  = hints.max_width  = width;
  561.     hints.height = hints.min_height = hints.max_height = height;
  562.     XSetNormalHints( dpy,win,&hints );
  563.     offx+=width+2*frame;
  564.  
  565.     XStoreName( dpy, win, name );
  566.     XSelectInput( dpy,win,ExposureMask );
  567.     XMapRaised( dpy, win );
  568.     XWindowEvent( dpy, win, ExposureMask, &event );
  569.     return win;
  570. }
  571.  
  572. void InitGraphic( double x, double y )
  573. {
  574. XSetWindowAttributes    setwinattr;
  575.  
  576. #if (SOUND_SUBSYSTEM)
  577.     if (sound_request)        init_sound( "" );
  578. #endif
  579.  
  580.     dpy = XOpenDisplay( "" );
  581.     if (!dpy) {
  582.         fprintf( stderr, "can't open display\n" );
  583.         exit(0);
  584.     }
  585.     scr = DefaultScreen(dpy);
  586.  
  587. #ifdef STATISTICS
  588.     fs=XLoadQueryFont(dpy,"5x8");
  589.     if (!fs) {    fs=XLoadQueryFont(dpy,"6x10");
  590.                 if (!fs)    fs=XLoadQueryFont(dpy,"fixed");
  591.     }
  592.     if (fs) {
  593.         info_font = fs->fid;
  594.         info_cw   = XTextWidth(fs,"A",1);
  595.         info_ch   = fs->ascent + fs->descent;
  596.     }
  597. #endif
  598.  
  599. //
  600. // Gr÷▀e des Fensters bestimmen: Fenster zentrieren
  601. //
  602. int    dp_height = DisplayHeight(dpy,scr)-info_ch;
  603.  
  604.     world_x = x;
  605.     world_y = y;
  606.     if ( size>0 ) {
  607.         if (size>DisplayWidth(dpy,scr))        size = DisplayWidth(dpy,scr);
  608.         max_x = size;
  609.         max_y = (int)(size/world_x*world_y);
  610.         if (max_y>dp_height) {
  611.             max_y = dp_height;
  612.             size = max_x = (int)(max_y/world_y*world_x);
  613.         }
  614.     }
  615.     else if ( ((double)DisplayWidth(dpy,scr))/dp_height < world_x/world_y ) {
  616.         max_x  = DisplayWidth(dpy,scr);
  617.         max_y = (int)(max_x/world_x*world_y);
  618.     }
  619.     else {
  620.         max_y = dp_height;
  621.         max_x = (int)(max_y/world_y*world_x);
  622.     }
  623.  
  624. //
  625.     if ( size<=0 ) {
  626.         setwinattr.override_redirect = True;
  627.         new_root = XCreateSimpleWindow( dpy, RootWindow( dpy, scr ),
  628.                     0, 0, DisplayWidth( dpy,scr ), DisplayHeight( dpy,scr ),
  629.                     0, WhitePixel( dpy,scr ), BlackPixel( dpy,scr ) );
  630.         XChangeWindowAttributes( dpy, new_root, CWOverrideRedirect, &setwinattr );
  631.  
  632.         win = XCreateSimpleWindow( dpy, new_root,
  633.                     (DisplayWidth( dpy,scr )-max_x)/2,
  634.                     (dp_height-max_y)/2,
  635.                     max_x, max_y, 0, BlackPixel( dpy,scr ),WhitePixel( dpy,scr ) );
  636.         XSelectInput( dpy, new_root, KeyPressMask );
  637.         XSelectInput( dpy, win, ExposureMask|KeyPressMask );
  638.         setwinattr.backing_store = (0)?Always:NotUseful;
  639.         setwinattr.bit_gravity   = ForgetGravity;;
  640.         XChangeWindowAttributes(dpy,win,CWBitGravity|CWBackingStore,&setwinattr );
  641.         w2n = (max_x-2)/world_x;
  642.     }
  643.     else {
  644.         new_root = 0;
  645.         win = XCreateSimpleWindow( dpy, RootWindow( dpy, scr ),
  646.                     0,0 , max_x, max_y, 2, 0,0 );
  647.         XSelectInput( dpy, win, KeyPressMask|ExposureMask);
  648.         setwinattr.backing_store = (0)?Always:NotUseful;
  649.         setwinattr.bit_gravity   = ForgetGravity;;
  650.         XChangeWindowAttributes(dpy,win,CWBitGravity|CWBackingStore,&setwinattr );
  651.         w2n = (max_x-2)/world_x;
  652.     }
  653.  
  654. //
  655. // BellPitch einstellen
  656. //
  657.     InitTime();                    // Initialisierung der Zeitmessung
  658. }
  659.  
  660.  
  661. void CloseGraphic()
  662. {
  663. #ifdef STATISTICS
  664.     if (fs)        XFreeFont(dpy,fs);
  665. #endif
  666.     XFreePixmap( dpy, pointer_pmap );
  667.     XFreePixmap( dpy, stipple_pmap );
  668.  
  669.     XFreeGC( dpy, gc_default );
  670.  
  671.     XFreeGC( dpy, gc_lay1 );
  672.     XFreeGC( dpy, gc_lay2 );
  673.     XFreeGC( dpy, gc_cursor );
  674.  
  675.     XFreeGC( dpy, gc_bxor );
  676.     XFreeGC( dpy, gc_bclear );
  677.  
  678.     if (deluxe)        XFreeGC( dpy, gc_ballwhite );
  679.     for (int i=0;i<nball_ids;i++) {
  680.         XFreeGC( dpy, gc_ball[i] );
  681.     }
  682.  
  683. #ifdef STATISTICS
  684.     XFreeGC( dpy, gc_text );
  685. #endif
  686.  
  687.     if (new_root) {
  688.         XUninstallColormap( dpy, cmap );
  689.     }
  690.     if (cmap!=DefaultColormap( dpy, scr )) {
  691.         XFreeColormap(dpy,cmap);
  692.     }
  693.  
  694.     end_sound();
  695.     XSync( dpy, 0 );
  696.     XCloseDisplay( dpy );
  697. }
  698.  
  699.  
  700.  
  701.  
  702.  
  703. char    GetKey()
  704. {
  705. XEvent    event;
  706.  
  707.     XSync( dpy, 0 );
  708.     while (XEventsQueued( dpy, QueuedAfterFlush )) {
  709.         XNextEvent( dpy, &event );
  710.         switch( event.xany.type ) {
  711.         case KeyPress:
  712.         {    char                buffer;
  713.             XComposeStatus    compose;
  714.             KeySym            keysym;
  715.  
  716.             XLookupString( (XKeyEvent*)&event, &buffer, 1, &keysym, &compose );
  717.             if (isupper(buffer))        return tolower(buffer);
  718.             return buffer;
  719.         }
  720.         case Expose:
  721.         {
  722.             while( XCheckMaskEvent( dpy, ExposureMask, &event ));
  723.             XClearWindow( dpy, win );
  724.             g->ExposeRedraw();
  725.             PBallTop::ForAll( &PBallTop::Redraw );
  726.             break;
  727.         }
  728.         default:
  729.             break;
  730.         }
  731.     }
  732.     return 0;
  733. }
  734.  
  735.  
  736. #define XPix(x)    ((int)((x)*w2n))
  737. #define YPix(y)    ((int)((y)*w2n))
  738. #define Pix(r)        ((int)((r)*w2n))
  739.  
  740. void DrawLine( const Real& x1, const Real& y1, const Real& x2, const Real& y2 ) {
  741. int    px1 = XPix(x1);
  742. int    py1 = YPix(y1);
  743. int    px2 = XPix(x2);
  744. int    py2 = YPix(y2);
  745.     XDrawLine( dpy, win, gc_current, px1, py1, px2, py2 );
  746. }
  747.  
  748.  
  749. void DrawArc( const Real& x, const Real& y, const Real& r, const Real& from, const Real& angle ) {
  750. int    px  = XPix(x-r);
  751. int    py  = YPix(y-r);
  752. int    size= Pix(2.*r);
  753.  
  754.     XDrawArc( dpy, win, gc_current,
  755.                 px, py, size, size,
  756.                 (int)(from*64.), (int)(angle*64.) );
  757. }
  758.  
  759.  
  760. void DrawCircle( const Real& x, const Real& y, const Real& r ) {
  761. int    px  = XPix(x-r);
  762. int    py  = YPix(y-r);
  763. int    size= Pix(2.*r);
  764.  
  765.     XDrawArc( dpy, win, gc_current,
  766.                 px, py, size, size,
  767.                 0, (int)360*64 );
  768. }
  769.  
  770.  
  771. void FillArc( const Real& x, const Real& y, const Real& r, const Real& from, const Real& angle ) {
  772. int    px  = XPix(x-r);
  773. int    py  = YPix(y-r);
  774. int    size= Pix(2.*r);
  775.  
  776.     XFillArc( dpy, win, gc_current,
  777.                 px, py, size, size,
  778.                 (int)(from*64.), (int)(angle*64.) );
  779. }
  780.  
  781. void FillCircle( const Real& x, const Real& y, const Real& r ) {
  782. int    px  = XPix(x-r);
  783. int    py  = YPix(y-r);
  784. int    size= Pix(2.*r);
  785.  
  786.     XFillArc( dpy, win, gc_current,
  787.                 px, py, size, size,
  788.                 0, (int)360*64 );
  789. }
  790.  
  791.  
  792. void FillRectangle( const Real& x, const Real& y, const Real& width, const Real& height ) {
  793. int    px1 = XPix(x);
  794. int    py1 = YPix(y);
  795. int    px2 = XPix(x+width);
  796. int    py2 = YPix(y+height);
  797.     XFillRectangle( dpy, win, gc_current, px1, py1, px2-px1, py2-py1 );
  798. }
  799.  
  800. void FillPoly( int n, ... ) {
  801. va_list    argptr;
  802. Vec2    *v;
  803. int        i;
  804. XPoint    buffer[10];
  805. XPoint    *p;                // Zeiger auf Puffer, um gegebenenfalls mehr anzufordern
  806.  
  807.     va_start(argptr,n);
  808.  
  809.     if (sizeof(buffer)/sizeof(XPoint)<n)    p=new XPoint[n];
  810.     else                                                p=buffer;
  811.  
  812.     for (i=0;i<n;i++) {
  813.         v =  va_arg(argptr,Vec2*);
  814.         p[i].x = XPix(v->X());
  815.         p[i].y = YPix(v->Y());
  816.  
  817.     }
  818.     XFillPolygon( dpy,win,gc_current,p,n,0,0);
  819.  
  820.     if (p!=buffer)                                    delete p;
  821.     va_end(arg_ptr);
  822. }
  823.  
  824. void FillPoly( int n, Vec2 v[] ) {
  825. int        i;
  826. XPoint    buffer[10];
  827. XPoint    *p;
  828.  
  829.     if (sizeof(buffer)/sizeof(XPoint)<n)    p=new XPoint[n];
  830.     else                                                p=buffer;
  831.  
  832.     for (i=0;i<n;i++) {
  833.         p[i].x = XPix(v[i].X());
  834.         p[i].y = YPix(v[i].Y());
  835.     }
  836.     XFillPolygon( dpy,win,gc_current,p,n,0,0);
  837.  
  838.     if (p!=buffer)                                    delete p;
  839. }
  840.  
  841.  
  842. E 1
  843.